﻿#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QIcon>
#include <QPixmap>
#include <QGridLayout>
#include <QLabel>
#include <QButtonGroup>
#include <QDebug>
#include <QDate>
#include <QTime>
#include <QMessageBox>
#include <QStringList>
#include <QTimer>
#include <QScrollBar>
#include <netconnection.h>
#include <QDataStream>
#include <QImage>
#include <QBuffer>

//很多东西调用不了就是没有加头文件，尤其是表格这一块

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setWindowTitle("自动对接");

    //初始化必要的菜单栏和功能栏目组件
    creatAction();
    creatMenus();
    creatToolbars();
    //初始化左边的选择栏目
    itemWeidgetInit();

    //创建了网络连接的对话框口，但是并不进行显示输出
    NetWidget = new NetConnection();

    //通过指针的当时获取此时的车牌
    CarNumberList = NetWidget->getCarNumberList();

    scene = new MBaseScene();
    //scene->setSceneRect(-250,-250,500,500);
    //设置了相应的scene大小后就不会再出现无线扩大的情况、
    //后期可以根据屏幕的相关尺寸进行一个调整，将所有控件的尺寸全部定

    //创建一个水平布局管理
    QHBoxLayout* layout = new QHBoxLayout;
    layout->addWidget(ItemWidget);

    view = new MBaseView(scene);

    view->setFixedSize(1200, 800);
    //view->setMinimumSize(900,600);
    layout->addWidget(view);
    //将这种水平布局给一个widget
    QWidget* widget = new QWidget;
    widget->setLayout(layout);
    //将这个小布局放在大的布局中进行显示
    setCentralWidget(widget);//Qmianwindow的一方法，实现主窗口的
    this->setWindowIcon(QIcon(":/image/Logo.png"));


    //状态表格初始化和生成
    ForStateWidget();
    SetupStateWidget();

    //刷新当前状态显示
    QTimer* timer = new QTimer(this);
    timer->start(2500);
    connect(timer, SIGNAL(timeout()), this, SLOT(slotStateToNew()));

    //刷新箭头的颜色，尽可能快没有延迟
    QTimer* timer1 = new QTimer(this);
    timer1->start(5);
    connect(timer1, &QTimer::timeout, this, &MainWindow::slotToNewLineColor);


    //将当前状态做一个发送,是以图片的格式做一个传送
    connect(timer, SIGNAL(timeout()), this, SLOT(slotStateToSend()));

    //连接状态改变
    connect(NetWidget, &NetConnection::signalsendCarState, this, &MainWindow::slotgetCarState);

    //接受总控发来的图
    connect(NetWidget, &NetConnection::singalsendSceneState, this, &MainWindow::slotSceneStateShow);

    //删除箭头
    connect(this, &MainWindow::signalAllisAtOrigin, this, &MainWindow::slotReallyDel);

    //发送插座松开到位的信号
    connect(this, &MainWindow::signaltheSocketisAtOrigin, this, &MainWindow::slotToSendtheSocketisAtOrigin);


}

MainWindow::~MainWindow()
{
    delete ui;
}


//这里要区别按钮信号的形式和两种槽函数的写法
void MainWindow::creatAction()
{
    exitAction = new QAction(tr("Exit"));
    connect(exitAction, SIGNAL(triggered()), this, SLOT(close()));

    logsAction = new QAction(tr("Logs"));
    connect(logsAction, SIGNAL(triggered()), this, SLOT(slotSceneState()));

    connectAction = new QAction(tr("NetSet"));
    connect(connectAction, SIGNAL(triggered()), this, SLOT(slotNetshow()));

    exportAction = new QAction(tr("Export"));
    connect(exportAction, SIGNAL(triggered()), this, SLOT(slotSceneSave()));

    ImportAction = new QAction(tr("Import"));
    connect(ImportAction, SIGNAL(triggered()), this, SLOT(slotSceneImport()));

}

//创建菜单栏目
void MainWindow::creatMenus()
{
    fileMenu = menuBar()->addMenu(tr("文件"));
    fileMenu->addAction(exitAction);
    fileMenu->addAction(logsAction);
    fileMenu->addAction(exportAction);
    fileMenu->addAction(ImportAction);


    setMenu = menuBar()->addMenu(tr("设置"));
    setMenu->addAction(connectAction);

}

//创建功能按钮栏目
void MainWindow::creatToolbars()
{
    //鼠标的操作按钮
    mouseToolbtn = new QToolButton;
    mouseToolbtn->setIcon(QIcon(":/image/mouse.png"));
    connect(mouseToolbtn, &QToolButton::clicked, this, &MainWindow::slotLineTomouse);
    mouseToolbar = addToolBar(tr("mosue"));
    mouseToolbar->addWidget(mouseToolbtn);

    //全场景的聚焦按钮
    centerToolbtn = new QToolButton;
    centerToolbtn->setIcon(QIcon(":/image/center.png"));
    connect(centerToolbtn, &QToolButton::clicked, this, &MainWindow::slotCenterOn);
    centerToolbar = addToolBar(tr("scene"));
    centerToolbar->addWidget(centerToolbtn);

    //对图元进行操作的按钮合集
    TLeftToolbtn = new QToolButton;
    TLeftToolbtn->setIcon(QIcon(":/image/TLeft.png"));
    connect(TLeftToolbtn, &QToolButton::clicked, this, &MainWindow::slotTLeft);

    TRightToolbtn = new QToolButton;
    TRightToolbtn->setIcon(QIcon(":/image/TRight.png"));
    connect(TRightToolbtn, &QToolButton::clicked, this, &MainWindow::slotTRight);

    DeleteToolbtn = new QToolButton;
    DeleteToolbtn->setIcon(QIcon(":/image/Delete.png"));
    connect(DeleteToolbtn, &QToolButton::clicked, this, &MainWindow::slotDelete);

    ItemOpToolbar = addToolBar(tr("ItemOP"));
    ItemOpToolbar->addWidget(TLeftToolbtn);
    ItemOpToolbar->addWidget(TRightToolbtn);
    ItemOpToolbar->addWidget(DeleteToolbtn);

    //状态表格显示按钮
    StateToolbtn =  new QToolButton;
    StateToolbtn->setCheckable(true);
    StateToolbtn->setIcon(QIcon(":/image/Form.png"));
    StateToolbar = addToolBar(tr("state form"));
    StateToolbar->addWidget(StateToolbtn);
    connect(StateToolbtn, &QToolButton::clicked, this, &MainWindow::slotStateForm);


    //对接执行
    LoadToolbtn = new QToolButton;
    LoadToolbtn->setIcon(QIcon(":/image/Load.png"));
    LoadToolbar = addToolBar(tr("Load"));
    LoadToolbar->addWidget(LoadToolbtn);
    connect(LoadToolbtn, &QToolButton::clicked, this, &MainWindow::slotLoadtodo);
}



void MainWindow::itemWeidgetInit()
{
    QFont font;
    font.setBold(true);
    font.setFamily("Time new Roman");

    //连线图元
    LineButton = new QToolButton;
    LineButton->setIcon(QIcon(QPixmap(":/image/Line.png")));
    LineButton->setIconSize(QSize(140, 90));
    LineButton->setAutoRaise(true);
    QGridLayout* LineLayout = new QGridLayout;
    LineLayout->addWidget(LineButton, 0, 0, Qt::AlignHCenter);
    //创建label，方便对字的属性进行修改
    QLabel* labelline = new QLabel;
    labelline->setFont(font);
    labelline->setText("连接线");
    LineLayout->addWidget(labelline, 1, 0, Qt::AlignCenter);
    LineLayout->setSizeConstraint(QLayout::SetFixedSize);//设置图片和文字的间距离为固定的，不根据父容器发生变化
    QWidget* LineWidget = new QWidget;
    LineWidget->setLayout(LineLayout);
    connect(LineButton, &QToolButton::clicked, this, &MainWindow::slotButLine);

    //供电车图元选项
    GD_carButton = new QToolButton;
    GD_carButton->setIcon(QIcon(QPixmap(":/image/GD_car.png")));
    GD_carButton->setIconSize(QSize(140, 90));
    GD_carButton->setAutoRaise(true);//设置扁平化，颜色背景保持一致
    QGridLayout* GD_carLayout = new QGridLayout;
    GD_carLayout->addWidget(GD_carButton, 0, 0, Qt::AlignHCenter);
    QLabel* labelGDcar = new QLabel;
    labelGDcar->setFont(font);
    labelGDcar->setText("GD型车");
    GD_carLayout->addWidget(labelGDcar, 1, 0, Qt::AlignCenter);
    GD_carLayout->setSizeConstraint(QLayout::SetFixedSize);//设置图片和文字的间距离为0
    QWidget* GD_carWidget = new QWidget;
    GD_carWidget->setLayout(GD_carLayout);
    connect(GD_carButton, &QToolButton::clicked, this, &MainWindow::slotButGD_car);


    //储能车图元选项
    CN_carButton = new QToolButton;
    CN_carButton->setIcon(QIcon(QPixmap(":/image/CN_car.png")));
    CN_carButton->setIconSize(QSize(140, 90));
    CN_carButton->setAutoRaise(true);
    QGridLayout* CN_carLayout = new QGridLayout;
    CN_carLayout->addWidget(CN_carButton, 0, 0, Qt::AlignHCenter);
    QLabel* labelCNcar = new QLabel;
    labelCNcar->setFont(font);
    labelCNcar->setText("CN型车");
    CN_carLayout->addWidget(labelCNcar, 1, 0, Qt::AlignCenter);
    CN_carLayout->setSizeConstraint(QLayout::SetFixedSize);
    QWidget* CN_carWidget = new QWidget;
    CN_carWidget->setLayout(CN_carLayout);
    connect(CN_carButton, &QToolButton::clicked, this, &MainWindow::slotButCN_car);


    //发射车图元选项
    FS_carButton = new QToolButton;
    FS_carButton->setIcon(QIcon(QPixmap(":/image/FS_car.png")));
    FS_carButton->setIconSize(QSize(140, 90));
    FS_carButton->setAutoRaise(true);
    QGridLayout* FS_carLayout = new QGridLayout;
    FS_carLayout->addWidget(FS_carButton, 0, 0, Qt::AlignHCenter);
    QLabel* labelFScar = new QLabel("FS型车");
    labelFScar->setFont(font);
    FS_carLayout->addWidget(labelFScar, 1, 0, Qt::AlignCenter);
    FS_carLayout->setSizeConstraint(QLayout::SetFixedSize);
    QWidget* FS_carWidget = new QWidget;
    FS_carWidget->setLayout(FS_carLayout);
    connect(FS_carButton, &QToolButton::clicked, this, &MainWindow::slotButFS_car);

    //创建一个网格布局管理
    QGridLayout* ItemLayout = new QGridLayout;
    ItemLayout->addWidget(LineWidget, 0, 0);
    ItemLayout->addWidget(GD_carWidget, 1, 0);
    ItemLayout->addWidget(CN_carWidget, 2, 0);
    ItemLayout->addWidget(FS_carWidget, 3, 0);
    ItemWidget = new QWidget;
    ItemWidget->setLayout(ItemLayout);



    //   QButtonGroup *buttongroup = new QButtonGroup;
    //   LineButton->setText("button1");
    //   GD_carButton->setText("button2");
    //   CN_carButton->setText("button3");
    //   FS_carButton->setText("button4");
    //   buttongroup->addButton(LineButton);
    //   buttongroup->addButton(GD_carButton);
    //   buttongroup->addButton(FS_carButton);
    //   buttongroup->addButton(CN_carButton);
    //   buttongroup->setExclusive(true);

}

void MainWindow::ForStateWidget()
{
    //状态表显示
    StateWidget = new QTableWidget();
    StateWidget->setWindowTitle(tr("State Table"));
    StateWidget->setWindowFlag(Qt::WindowStaysOnTopHint);//设置始终在最上层
    StateWidget->setEditTriggers(QAbstractItemView::NoEditTriggers);//设置表格的内容不能够被修改
    StateWidget->setSelectionBehavior(QAbstractItemView::SelectRows);
    StateWidget->setWindowFlag(Qt::SubWindow);//子窗口
    StateWidget->verticalScrollBar()->setDisabled(true);
    StateWidget->horizontalScrollBar()->setDisabled(true);
    StateWidget->setColumnCount(5);
    QFont font;
    font.setBold(true);
    font.setFamily("Time new Roman");
    font.setPointSize(9);
    StateWidget->setFont(font);
    //设置表头
    QStringList Headers;
    QTableWidgetItem* headerItem;
    Headers << "Car Number" << "Plug" << "Car Number" << "Socket" << "State";
    for(int i = 0 ; i < StateWidget->columnCount(); i++)
    {
        QFont font;
        font.setBold(true);
        font.setFamily("Time new Roman");
        font.setPointSize(10);
        headerItem = new QTableWidgetItem(Headers.at(i));
        headerItem->setFont(font);
        StateWidget->setHorizontalHeaderItem(i, headerItem);
    }

    //设置表格每列的宽度
    StateWidget->setColumnWidth(0, 130);
    StateWidget->setColumnWidth(1, 80);
    StateWidget->setColumnWidth(2, 130);
    StateWidget->setColumnWidth(3, 80);
    StateWidget->setColumnWidth(4, 130);
}


void MainWindow::SetupStateWidget()
{
    //表格初始化函数,主要初始化列
    int LineItemsCount = 0;
    QList<QGraphicsItem*> items = scene->items();
    foreach(QGraphicsItem* item, items)
    {
        if(item->type() == Line_Object::Type)
        {
            LineItemsCount ++;
        }
    }
    StateWidget->setRowCount(LineItemsCount);
    int Rowcount = 0;
    foreach(QGraphicsItem* item, items)
    {
        if(item->type() == Line_Object::Type)
        {
            Line_Object* LocateItem = qgraphicsitem_cast<Line_Object*>(item);
            if(LocateItem && LocateItem->getStartItem()->Type == PlugObject::Type
                    && LocateItem->getEndItem()->type() == SocketObject::Type)
            {
                //在这里实现表格的完全定义
                QTableWidgetItem* itemSN = new QTableWidgetItem(LocateItem->getStartItem()->getcarNumber());
                itemSN->setTextAlignment(Qt::AlignCenter);
                StateWidget->setItem(Rowcount, 0, itemSN);

                QTableWidgetItem* itemSP = new QTableWidgetItem(LocateItem->getStartItem()->getPlugName());
                itemSP->setTextAlignment(Qt::AlignCenter);
                StateWidget->setItem(Rowcount, 1, itemSP);

                QTableWidgetItem* itemEN = new QTableWidgetItem(LocateItem->getEndItem()->getcarNumber());
                itemEN->setTextAlignment(Qt::AlignCenter);
                StateWidget->setItem(Rowcount, 2, itemEN);

                QTableWidgetItem* itemES = new QTableWidgetItem(LocateItem->getEndItem()->getSocketName());
                itemES->setTextAlignment(Qt::AlignCenter);
                StateWidget->setItem(Rowcount, 3, itemES);

                //这里显示对接状态
                QTableWidgetItem* itemST = new QTableWidgetItem(LocateItem->getLineState());
                itemST->setTextAlignment(Qt::AlignCenter);
                StateWidget->setItem(Rowcount, 4, itemST);
            }
            Rowcount ++;
        }
    }
//    qDebug() << "The ConnectingItem is" << Rowcount ;
    int statewidgetheight  = StateWidget->rowHeight(0) * Rowcount;
    StateWidget->resize(565, statewidgetheight + 80);
}


//表格信息的刷新不应该在这里进行这里应该只作为表格的显示
//表格的刷新应该在后台检测到连接状态变化时进行刷新
void MainWindow::slotStateForm()
{
    if(StateToolbtn->isChecked())
    {
        SetupStateWidget();
        StateWidget->show();
    }
    else
    {
        StateWidget->close();
    }
}


//这里是实时刷新当前scene的状态，并且只有在固定条件下才显示
void MainWindow::slotStateToNew()
{
    SetupStateWidget();
    if(StateToolbtn->isChecked())
        StateWidget->show();
}



//插入供电车的槽函数
void MainWindow::slotButGD_car()
{
    MBaseObject* item = new mGD_car_object();
    item->setPos(view->LocatePoint);
    //添加carNumberList到相关的可选库中
    item->AddCarNumbertoCarnumbers(CarNumberList);
    view->scene()->addItem(item);
    scene->EnableDrawLine(false);

}

//插入储能车的槽函数
void MainWindow::slotButCN_car()
{
    MBaseObject* item = new mCN_car_object();
    item->setPos(view->LocatePoint);
    item->AddCarNumbertoCarnumbers(CarNumberList);
    view->scene()->addItem(item);
    scene->EnableDrawLine(false);
}

//插入发射车的函数
void MainWindow::slotButFS_car()
{
    MBaseObject* item = new mFS_car_object();
    //这里指向的是view中的变量
    item->setPos(view->LocatePoint);
    item->AddCarNumbertoCarnumbers(CarNumberList);
    view->scene()->addItem(item);
    scene->EnableDrawLine(false);
}


//有关通信相关的程序
void MainWindow::slotNetshow()
{
    //这里因该是无需刷新的，直接对接后台的控制程序
    //只是作为显示出来更加直观而已
    NetWidget->show();
}


//插入连接线的函数
void MainWindow::slotButLine()
{
    scene->EnableDrawLine(true);
}

//取消画线状态，进入鼠标拖拽状态
void MainWindow::slotLineTomouse()
{
    scene->EnableDrawLine(false);
}

//激活场景图元获取的函数
void MainWindow::slotSceneState()
{
    qDebug() << "slotSceneState is ok";
    SceneState(this->scene);
}

//在这里检测所有车之间的连接状态,并输出相关操作日志
void MainWindow::SceneState(QGraphicsScene* scene)
{
    //写每一次操作的时间Log
    QFile data("Log.txt");
    if(data.open(QFile::Append))
    {
        QTextStream out(&data);
        out << QDate::currentDate().toString() << "  " << QTime::currentTime().toString() << endl;
        data.close();
    }
    //开始扫描连接状态
    QList<QGraphicsItem*> items = scene->items();
    foreach(QGraphicsItem* item, items)
    {
        if(item->type() == Line_Object::Type)
        {
            Line_Object* LocateItem = qgraphicsitem_cast<Line_Object*>(item);
            if(LocateItem && LocateItem->getStartItem()->Type == PlugObject::Type
                    && LocateItem->getEndItem()->type() == SocketObject::Type)
            {
                //继续续写
                if(data.open(QFile::Append))
                {
                    QTextStream out(&data);
                    out << LocateItem->getStartItem()->getcarNumber() << "  "
                        << LocateItem->getStartItem()->getPlugName() << "  "
                        << LocateItem->getEndItem()->getcarNumber() << "  "
                        << LocateItem->getEndItem()->getSocketName() << "  "
                        << "Connected" << endl;
                    data.close();
                }
                //在这里实现连接表的打印，或者在这里实现后期需要控制信息的汇总
                qDebug() << LocateItem->getStartItem()->getcarNumber()
                         << LocateItem->getStartItem()->getPlugName()
                         << LocateItem->getEndItem()->getcarNumber()
                         << LocateItem->getEndItem()->getSocketName()
                         << "Connect!";
            }
        }
    }
}

//场景聚焦函数
void MainWindow::slotCenterOn()
{
    QRectF ItemsBoudingRect;
    ItemsBoudingRect = this->scene->itemsBoundingRect();
    QRectF SceneRect = ItemsBoudingRect.adjusted(-25, -25, 50, 50);
    view->fitInView(SceneRect, Qt::KeepAspectRatio);

    //    int count = 0;
    //    QPointF itemsCenter;
    //    foreach (QGraphicsItem* item, scene->items()) {
    //        if(item->type() == mCN_car_object::Type
    //                | item->type() == mFS_car_object::Type
    //                | item->type() == mGD_car_object::Type){
    //            itemsCenter += item->scenePos();
    //            count++;
    //        }

    //    }
    //    itemsCenter /= count; // 计算平均值

    //    // 将视图滚动到所有项的平均位置
    //    view->centerOn((itemsCenter));
}

void MainWindow::slotTLeft()
{
    foreach (QGraphicsItem* item, scene->selectedItems())
    {
        if (item->type() != Line_Object::Type)
        {
            qreal offset;
            offset = item->rotation() - 90;
            item->setRotation(offset);
        }
    }
}

void MainWindow::slotTRight()
{
    foreach (QGraphicsItem* item, scene->selectedItems())
    {
        if (item->type() != Line_Object::Type)
        {
            qreal offset;
            offset = item->rotation() + 90;
            item->setRotation(offset);
        }
    }
}


//检测箭头，加载进行执行
void MainWindow::slotLoadtodo()
{
    QMessageBox msgBox;
    msgBox.setWindowIcon(QIcon(":/image/SmallWIn.png"));
    msgBox.setText("Hint");
    msgBox.setInformativeText(tr("Load to Connect?"));
    msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
    msgBox.setDefaultButton(QMessageBox::No);
    if( msgBox.exec() == QMessageBox::Yes)
    {
        //在这里开始定时请求设备状态、对接状态，这里直接全体请求
        NetWidget->onTimetoRequestEveryCar();
        //遍历，发送对接的消息
        foreach(QGraphicsItem* item, this->scene->items())
        {
            if (item->type() == Line_Object::Type)
            {
                Line_Object* LocateItem = qgraphicsitem_cast<Line_Object*>(item);
                if(LocateItem && LocateItem->getStartItem()->Type == PlugObject::Type
                        && LocateItem->getEndItem()->type() == SocketObject::Type)
                {
                    //这里分carNumber包含了前5位的车牌和后面的Ip
                    QString StartItemMsg = LocateItem->getStartItem()->getcarIP();
                    QString EndItemMsg = LocateItem->getEndItem()->getcarIP();
                    QString loadMsg = LocateItem->getStartItem()->getPlugNumber() + LocateItem->getEndItem()->getsocketNumber();
                    qDebug() << loadMsg;
                    //调用网络接口实现信息的发送
                    NetWidget->LoadtoConnect(LocateItem->getStartItem()->getPlugNumber(),
                                             LocateItem->getEndItem()->getsocketNumber(),
                                             StartItemMsg,  EndItemMsg);
                }
            }
        }

    }
    else
    {
        return;
    }
}


//删除箭头的操作，断开连接，这里实现的是断开连接，可能误操作还要再写一个
void MainWindow::slotDelete()
{
    foreach (QGraphicsItem* item, scene->selectedItems())
    {
        if (item->type() != Line_Object::Type)
        {
            this->scene->removeItem(item);
            delete item;
        }
        //这里对箭头删除函数的相应，后期要通信
        else
        {
            QMessageBox msgBox;
            msgBox.setWindowIcon(QIcon(":/image/SmallWIn.png"));
            msgBox.setText("Hint");
            msgBox.setInformativeText(tr("Disconnect?"));
            msgBox.setStandardButtons(QMessageBox::Yes | QMessageBox::No);
            msgBox.setDefaultButton(QMessageBox::No);
            if( msgBox.exec() == QMessageBox::Yes)
            {
                //设置该Line的标志位disConnecting
                Line_Object* LocateItem = qgraphicsitem_cast<Line_Object*>(item);
                //点击了删除标志，这里将箭头属性转换成disconnecting
                LocateItem->IsDisCnting();
                //为了实现延迟删除的操作，这里不能直接删

                //发送指定指令到车
                if(LocateItem && LocateItem->getStartItem()->Type == PlugObject::Type
                        && LocateItem->getEndItem()->type() == SocketObject::Type)
                {
                    //这里分carNumber包含了前5位的车牌和后面的Ip
                    QString StartItemMsg = LocateItem->getStartItem()->getcarIP();
                    qDebug() <<  StartItemMsg;
                    QString EndItemMsg = LocateItem->getEndItem()->getcarIP();
                    qDebug() <<  EndItemMsg;
                    //调用网络接口实现信息的发送
                    NetWidget->LoadtoDisConnect(LocateItem->getStartItem()->getPlugNumber(),
                                                LocateItem->getEndItem()->getsocketNumber(),
                                                StartItemMsg,  EndItemMsg);
                }
            }
            else
            {
                return;
            }
            qDebug() << "this is to delete line!";
        }
    }
}

void MainWindow::slotReallyDel(Line_Object* item)
{
    //搜索删除
//    foreach (QGraphicsItem *item, scene->selectedItems()) {
//        if (item->type() == Line_Object::Type) {
//            Line_Object *theItem = qgraphicsitem_cast<Line_Object*>(item);
//            if(theItem->getLineState() == "DisConnecting!")
//                this->scene->removeItem(theItem);
//        }
//    }
    //直接传递过来删除
    if(item->getLineState() == "DisConnecting!")
        this->scene->removeItem(item);
}



//如果两个设备都回到零点，则删除该箭头
//接受车辆状态信号，对UI进行刷新
/*
 *@判断是否为车型,这里不必去遍历所有的车型，因为所有的插座已经绑定了1车型 2自身的位置属性，直接下到最低层的插座孔的层面去解决问题！
 *@还有一种办法就是前面的代码全部重构，将其将其在车型进行指针化，这样这边的判断逻辑更加清晰一些
 *@这里是直接面向最底层的
  if(item->type() == PlugObject::Type){
    PlugObject *theItem = qgraphicsitem_cast<PlugObject*>(item);
    if(theItem->getcarNumber() == carNumber) {}
*/
/* @@@ 这里为什么要进行自定义数据类型才能实现比较？
 * @@@ 前面哪些return的方法到底有什么作用，看着很整齐，但用法到底是什么 ！1寻求C++书 2看例程代码 */
void MainWindow::slotgetCarState(QString carState)
{
    //取前六位进行车辆上设备状态的判断
    QString mCarState = carState.mid(0, 6);
    QString carIP = carState.mid(6, carState.length() - 6);
    qDebug() << carIP << mCarState;

    QList<mCN_car_object*> CNItemList;
    QList<mFS_car_object*> FSItemList;
    QList<mGD_car_object*> GDItemList;
    //遍历所有图形，选出三种车型进行分类
    foreach (QGraphicsItem* item, this->scene->items())
    {
        switch(item->type())
        {
            case mCN_car_object::Type :
                {
                    mCN_car_object* theItem = qgraphicsitem_cast<mCN_car_object*>(item);//  强制转换
                    //将所有添加到一个自定义的QList的容器中
                    CNItemList.append(theItem);
                }
                break;
            case mFS_car_object::Type :
                {
                    mFS_car_object* theItem = qgraphicsitem_cast<mFS_car_object*>(item);
                    FSItemList.append(theItem);
                }
                break;

            case mGD_car_object::Type :
                {
                    mGD_car_object* theItem = qgraphicsitem_cast<mGD_car_object*>(item);
                    GDItemList.append(theItem);

                }
                break;
            default:
                break;
        }
    }
    //遍历结束将所有的发送判断,后期应该开三个线程同时去做这件事
    toNewCNcar(carIP, mCarState, CNItemList);
    toNewFScar(carIP, mCarState, FSItemList);
    toNewGDcar(carIP, mCarState, GDItemList);
}


void MainWindow::toNewCNcar(QString carIP, QString mCarState, QList<mCN_car_object*> CNitemList)
{
    foreach(mCN_car_object* theItem, CNitemList)
    {
        if(theItem->getCarIP() == carIP)
        {
            //在这里就能够直接操作车上插座的状态
            for (int i = 0; i < mCarState.size(); ++i)
            {
                if (mCarState.at(i) == '0')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC0();
                            break;
                        case 1:
                            theItem->getplugMleft()->mPCtoC0();
                            break;
                        case 2:
                            break;
                        case 3:
                            theItem->getsocketFright()->mSCtoC0();
                            break;
                        case 4:
                            theItem->getplugMright()->mPCtoC0();
                            break;
                        case 5:
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '1')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC1();
                            break;
                        case 1:
                            theItem->getplugMleft()->mPCtoC1();
                            break;
                        case 2:
                            break;
                        case 3:
                            theItem->getsocketFright()->mSCtoC1();
                            break;
                        case 4:
                            theItem->getplugMright()->mPCtoC1();
                            break;
                        case 5:
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '2')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC2();
                            break;
                        case 1:
                            theItem->getplugMleft()->mPCtoC2();
                            break;
                        case 2:
                            break;
                        case 3:
                            theItem->getsocketFright()->mSCtoC2();
                            break;
                        case 4:
                            theItem->getplugMright()->mPCtoC2();
                            break;
                        case 5:
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '3')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC3();
                            break;
                        case 1:
                            theItem->getplugMleft()->mPCtoC3();
                            break;
                        case 2:
                            break;
                        case 3:
                            theItem->getsocketFright()->mSCtoC3();
                            break;
                        case 4:
                            theItem->getplugMright()->mPCtoC3();
                            break;
                        case 5:
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }

            }
        }
    }
}

void MainWindow::toNewFScar(QString carIP, QString mCarState, QList<mFS_car_object*> FSitemList)
{
    foreach(mFS_car_object* theItem, FSitemList)
    {
        if(theItem->getCarIP() == carIP)
        {
            for (int i = 0; i < mCarState.size(); ++i)
            {
                if (mCarState.at(i) == '0')
                {
                    switch (i)
                    {
                        case 0:
                            break;
                        case 1:
                            break;
                        case 2:
                            theItem->getsocketBLeft()->mSCtoC0();
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        case 5:
                            theItem->getsocketBright()->mSCtoC0();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '1')
                {
                    switch (i)
                    {
                        case 0:
                            break;
                        case 1:
                            break;
                        case 2:
                            theItem->getsocketBLeft()->mSCtoC1();
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        case 5:
                            theItem->getsocketBright()->mSCtoC1();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '2')
                {
                    switch (i)
                    {
                        case 0:
                            break;
                        case 1:
                            break;
                        case 2:
                            theItem->getsocketBLeft()->mSCtoC2();
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        case 5:
                            theItem->getsocketBright()->mSCtoC2();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '3')
                {
                    switch (i)
                    {
                        case 0:
                            break;
                        case 1:
                            break;
                        case 2:
                            theItem->getsocketBLeft()->mSCtoC3();
                            break;
                        case 3:
                            break;
                        case 4:
                            break;
                        case 5:
                            theItem->getsocketBright()->mSCtoC3();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
            }
        }
    }
}



void MainWindow::toNewGDcar(QString carIP, QString mCarState, QList<mGD_car_object*> GDitemList)
{
    foreach(mGD_car_object* theItem, GDitemList)
    {
        if(theItem->getCarIP() == carIP)
        {
            for (int i = 0; i < mCarState.size(); ++i)
            {
                if (mCarState.at(i) == '0')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC0();
                            break;
                        case 1:
                            theItem->getsocketMLeft()->mSCtoC0();
                            break;
                        case 2:
                            theItem->getplugBleft()->mPCtoC0();
                            break;
                        case 3:
                            theItem->getplugFright()->mPCtoC0();
                            break;
                        case 4:
                            theItem->getsocketMright()->mSCtoC0();
                            break;
                        case 5:
                            theItem->getplugBright()->mPCtoC0();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '1')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC1();
                            break;
                        case 1:
                            theItem->getsocketMLeft()->mSCtoC1();
                            break;
                        case 2:
                            theItem->getplugBleft()->mPCtoC1();
                            break;
                        case 3:
                            theItem->getplugFright()->mPCtoC1();
                            break;
                        case 4:
                            theItem->getsocketMright()->mSCtoC1();
                            break;
                        case 5:
                            theItem->getplugBright()->mPCtoC1();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '2')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC2();
                            break;
                        case 1:
                            theItem->getsocketMLeft()->mSCtoC2();
                            break;
                        case 2:
                            theItem->getplugBleft()->mPCtoC2();
                            break;
                        case 3:
                            theItem->getplugFright()->mPCtoC2();
                            break;
                        case 4:
                            theItem->getsocketMright()->mSCtoC2();
                            break;
                        case 5:
                            theItem->getplugBright()->mPCtoC2();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
                if (mCarState.at(i) == '3')
                {
                    switch (i)
                    {
                        case 0:
                            theItem->getsocketFLeft()->mSCtoC3();
                            break;
                        case 1:
                            theItem->getsocketMLeft()->mSCtoC3();
                            break;
                        case 2:
                            theItem->getplugBleft()->mPCtoC3();
                            break;
                        case 3:
                            theItem->getplugFright()->mPCtoC3();
                            break;
                        case 4:
                            theItem->getsocketMright()->mSCtoC3();
                            break;
                        case 5:
                            theItem->getplugBright()->mPCtoC3();
                            break;
                        default: /* 处理其他情况或抛出错误 */
                            break;
                    }
                }
            }
        }
    }
}


//定时刷新箭头的颜色来显示对接状态
void MainWindow::slotToNewLineColor()
{
    foreach(QGraphicsItem* item, this->scene->items())
    {
        if(item && item->type() == Line_Object::Type)
        {
            Line_Object* theItem = qgraphicsitem_cast<Line_Object*>(item);
            // 机械臂运动，插座原位
            if( (theItem->getStartItem()->getIsMoving() && theItem->getEndItem()->getIsATOrigin()))
            {
                theItem->mLCtoMove();//箭头颜色为对接颜色
            }
            // 机械臂到位，插座运动
            else if( (theItem->getStartItem()->getIsConnected() && theItem->getEndItem()->getIsMoving()) )
            {
                theItem->mLCtoMove();//箭头颜色为对接颜色
            }
            //完成对接，两者都到对接位置
            else if(theItem->getStartItem()->getIsConnected() && theItem->getEndItem()->getIsConnected())
            {
                theItem->mLCtoCnted();//箭头颜色为完成对接颜色 这里设置了标志位connected
            }
            //两这全部回到原点且自检正常
            else if (theItem->getStartItem()->getIsATOrigin() && theItem->getEndItem()->getIsATOrigin())
            {
                emit signalAllisAtOrigin(theItem);
            }
            //断开时:机械臂是到位的，插座回到原点，机械臂才能够动作
            else if(theItem->getLineState() == "DisConnecting!" && theItem->getStartItem()->getIsConnected() && theItem->getEndItem()->getIsATOrigin())
            {
                //  这里直接调用函数发送到位的频率太高了，不可取
                //     NetWidget->SockethasReturntoOrigin(theItem->getStartItem()->getPlugNumber(), theItem->getStartItem()->getcarIP());
                emit signaltheSocketisAtOrigin(theItem);
            }
        }
        else
        {
            return;
        }
    }
}

// 解决上面发送速度过快的问题
void MainWindow::slotToSendtheSocketisAtOrigin(Line_Object* item)
{
    //不能如此频率的发送，只发送一次，或者较慢直到状态改变完成
    if(!item->gethasSendtheSocketisAtOrigin())
    {
        NetWidget->SockethasReturntoOrigin(item->getStartItem()->getPlugNumber(), item->getStartItem()->getcarIP());
    }
    //标志已经发送了
    item->changehasSendtheSocketisAtOrigin();

}



//在这里要熟悉了解一个比较重要的东西，就是这里的scene，view之间的大小究竟是什么关系，之间的比较是什么问题
void MainWindow::slotSceneSave()
{
    QRectF ItemsBoudingRect;
    ItemsBoudingRect = this->scene->itemsBoundingRect();
    QRectF SceneRect = ItemsBoudingRect.adjusted(-25, -25, 25, 25);
    QImage image(SceneRect.size().toSize(), QImage::Format_ARGB32);
    // 创建 QPainter 用于渲染场景
    QPainter painter(&image);
    //reder(画笔，画板，源文)
    this->scene->render(&painter, QRectF(), SceneRect);
    painter.setRenderHint(QPainter::Antialiasing, true);
    painter.setRenderHint(QPainter::SmoothPixmapTransform, true);
    //reder(画笔，画板，源文)
    // 保存图像为pNG文件
    image.save("scene.png");
}

void MainWindow::slotSceneImport()
{
    QPixmap pimap("scene.png");
    QGraphicsPixmapItem* pimapItem = new QGraphicsPixmapItem(pimap);
    pimapItem->setFlag(QGraphicsPixmapItem::ItemIsMovable);
    this->scene->addItem(pimapItem);
    view->centerOn(pimapItem);
}


//在这里实现对当前scene图表的发送
void MainWindow::slotStateToSend()
{
    if(NetWidget->getisAsServer())
    {
        QRectF ItemsBoudingRect;
        ItemsBoudingRect = this->scene->itemsBoundingRect();
        QRectF SceneRect = ItemsBoudingRect.adjusted(-20, -20, 20, 20);
        QImage image(SceneRect.size().toSize(), QImage::Format_ARGB32);
        image.fill(Qt::white);
        // 创建 QPainter 用于渲染场景
        QPainter painter(&image);

        painter.setRenderHint(QPainter::Antialiasing, true);
        painter.setRenderHint(QPainter::SmoothPixmapTransform, true);

        this->scene->render(&painter, QRectF(), SceneRect);

        //将图片编码成为base64数据，用于传输
        QByteArray imagebyteArray;
        QBuffer buffer(&imagebyteArray);
        image.save(&buffer, "PNG");
        NetWidget->sceneSynicing(imagebyteArray);
    }
}

//成为客户端后，接收相关的状态图片
void MainWindow::slotSceneStateShow(QString SceneState)
{
    this->scene->clear();
    QImage restoreImage;
    QByteArray imageData = QByteArray::fromBase64(SceneState.toLatin1());
    restoreImage.loadFromData(imageData);

    // 从恢复的图像创建pixmap项目
    QPixmap pixmap = QPixmap::fromImage(restoreImage);
    QGraphicsPixmapItem* pixmapItem = new QGraphicsPixmapItem(pixmap);
    pixmapItem->setFlag(QGraphicsPixmapItem::ItemIsMovable);
    this->scene->addItem(pixmapItem);
    view->centerOn(pixmapItem);
}
